package com.spring.bucks.config;

import com.alibaba.druid.filter.FilterChain;
import com.alibaba.druid.filter.FilterEventAdapter;
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy;
import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
import com.alibaba.druid.proxy.jdbc.StatementProxy;
import com.spring.bucks.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.sql.SQLException;
import java.util.Properties;

/**
 * @author 超
 * Create by fengc on  2022/8/20 15:46
 * 关注查询的sql拦截
 */
@Slf4j
public class MyDruidFilter extends FilterEventAdapter {

    @Override
    protected void statementExecuteBefore(StatementProxy statement, String sql) {
        log.info("进入...statementExecuteBefore...sql={}.",sql);
        if (sql.contains(";")) {
            throw new BusinessException("不允许进行 SQL 拼接");
        }
        if (sql.contains("in")) {
            checkSQL(sql);
        }
        super.statementExecuteBefore(statement, sql);
    }

    /**
     *  条件参数中，如果有 in ，in 列表不能超过 10 个。
     * @param sql
     */
    private void checkSQL(String sql) {
        int index = sql.indexOf("in");
        sql = sql.substring(index + 2);
        index = sql.indexOf("in");
        String checkSql ="";
        int lastIndex = index;
        if (index > 0) {
            checkSql = sql.substring(0,index);
        } else {
            lastIndex = sql.indexOf(")");
            checkSql = sql.substring(0,lastIndex);
        }
        int oldLength = checkSql.length();
        checkSql = checkSql.replace(",","");
        //由于是计算in里面的逗号的，所以得加上1
        int countIn = oldLength - checkSql.length() + 1;
        if (countIn > 10) {
            throw new BusinessException("sql中的参数in列表不能超过 10 个");
        }
        //继续判断后一段
        sql = sql.substring(lastIndex);
        checkSQL(sql);
    }

    @Override
    protected void statementExecuteAfter(StatementProxy statement, String sql, boolean result) {
        log.info("进入...statementExecuteAfter....");
        super.statementExecuteAfter(statement, sql, result);
    }
}
